package com.linkoog.devtools.metadata.raw_index;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.linkoog.devtools.raw_index.core.PsiClassRawFileIndex;
import com.linkoog.devtools.type.javadoc.JavaDocParser;
import com.linkoog.devtools.type.swagger.JavaSwaggerParser;
import com.linkoog.devtools.utils.PsiElementUtil;
import com.linkoog.devtools.utils.PsiMethodUtil;
import com.linkoog.devtools.utils.VirtualFileUtils;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Set;

public class ClassMetadataRawFileIndex extends PsiClassRawFileIndex<ClassMetadata> {

    public static final Key<Set<PsiElement>> key = Key.create("DevTools.ClassMetadataRawFileIndex.Key");

    public static ClassMetadataRawFileIndex getInstance(Project project){
        return EXTENSION_POINT_NAME.findExtension(ClassMetadataRawFileIndex.class, project);
    }

    @Override
    public Key<Set<PsiElement>> getPsiElementKey() {
        return key;
    }

    @Override
    public File getCacheFile(Project project) throws IOException{
        return new File(project.getBasePath() + "/.idea/index-data/MetaClass.idx");
    }

    @Override
    public Class<ClassMetadata> getCacheClass(Project project) {
        return ClassMetadata.class;
    }

    @Override
    public ClassMetadata resolve(PsiClass psiClass) {
        if (psiClass == null) return null;
        if (!isInit()) return null;

        final VirtualFile virtualFile = psiClass.getContainingFile().getOriginalFile().getVirtualFile();
        final long timestamp = VirtualFileUtils.getTimestamp(virtualFile);

        String moduleFilePath = PsiElementUtil.resolveModuleFilePath(psiClass);

        ClassMetadata classMetadata = new ClassMetadata(virtualFile.getUrl(), psiClass.getTextOffset(), psiClass.getQualifiedName(), moduleFilePath);
        classMetadata.initPsiElement(psiClass.getProject(), psiClass);
        classMetadata.setJavaDocSupplier(() -> JavaDocParser.parse(psiClass.getDocComment()));
        classMetadata.setSwaggerCommentSupplier(() -> JavaSwaggerParser.parseClass(psiClass));
        classMetadata.setTimestamp(timestamp);
        return classMetadata;
    }

    private LinkedHashMap<Integer, MethodMetadata> parseMethodMetadata(PsiClass psiClass){
        LinkedHashMap<Integer, MethodMetadata> methodMetadataList = new LinkedHashMap<>();
        for (PsiMethod psiMethod : psiClass.getAllMethods()) {
            if (PsiMethodUtil.isObjectMethod(psiMethod)) continue;

            MethodMetadata methodMetadata = MethodMetadataRawFileIndex.getInstance(project).getCache(psiMethod);
            if (methodMetadata != null){
                methodMetadataList.put(psiMethod.getTextOffset(), methodMetadata);
            }
        }
        return methodMetadataList;
    }



}
